import { createContext, useContext, useReducer, useMemo } from "react";

// prop-types is a library for typechecking of props
import PropTypes from "prop-types";

// React main context
const GlobalVariables = createContext();

// Setting custom name for the context which is visible on react dev tools
GlobalVariables.displayName = "GlobalVariablesContext";

// React reducer
function reducer(state, action) {
  switch (action.type) {
    case "ARIA2GETGLOBALSTAT": {
      return { ...state, aria2GetGlobalStat: action.value };
    }
    default: {
      throw new Error(`Unhandled action type: ${action.type}`);
    }
  }
}

// React context provider
function GlobalVariablesControllerProvider({ children }) {
  const initialState = {
    aria2GetGlobalStat: {
      downloadSpeed: "0",
      numActive: "0",
      numStopped: "0",
      numStoppedTotal: "0",
      numWaiting: "0",
      uploadSpeed: "0",
    },
  };

  const [controller, dispatch] = useReducer(reducer, initialState);

  const value = useMemo(() => [controller, dispatch], [controller, dispatch]);

  return <GlobalVariables.Provider value={value}>{children}</GlobalVariables.Provider>;
}

// React custom hook for using context
function useGlobalVariablesController() {
  const context = useContext(GlobalVariables);

  if (!context) {
    throw new Error(
      "useGlobalVariablesController should be used inside the GlobalVariablesControllerProvider."
    );
  }

  return context;
}

// Typechecking props for the GlobalVariablesControllerProvider
GlobalVariablesControllerProvider.propTypes = {
  children: PropTypes.node.isRequired,
};

// Context module functions
const setAria2GetGlobalStat = (dispatch, value) => dispatch({ type: "ARIA2GETGLOBALSTAT", value });

export { GlobalVariablesControllerProvider, useGlobalVariablesController, setAria2GetGlobalStat };
